#include "../source/prjlog.h"
#include <chrono>
void bench(const std::string &logger_name, size_t thr_count, size_t msg_count, size_t msg_len)
{
    // 1.获取日志器
    PRJLOG::Logger::ptr logger = PRJLOG::getLogger(logger_name);
    if (logger == nullptr)
    {
        return;
    }
    std::cout << "测试线程：" << thr_count << "个，测试消息数量：" << msg_count
              << "条，测试消息总大小：" << (msg_count * msg_len) / 1024 << "KB\n";
    // 2.组织指定长度的日志消息
    std::string msg(msg_len - 1, 'A'); // 留一个字符放\n
    // 3.创建指定数量的线程
    std::vector<std::thread> threads;
    std::vector<double> cost_arry(thr_count);
    size_t msg_per_thr = msg_count / thr_count; // 消息个数/线程个数=每个线程处理的消息个数
    for (int i = 0; i < thr_count; i++)
    {
        threads.emplace_back([&, i]()
                             {
           // 4.开始计时-线程内部计时，不包括线程创建时间
           auto start = std::chrono::high_resolution_clock::now();
           // 5.循环写日志消息
           for (int j = 0; j < msg_per_thr; j++)
           {
            logger->fatal("%s",msg.c_str());
           }
           // 6.结束计时
           auto end = std::chrono::high_resolution_clock::now();
           std::chrono::duration<double> cost = end-start;
           cost_arry[i]=cost.count();
           std::cout<<"线程"<<i<<": \t输出数量"<<msg_per_thr
           <<"条，耗时："<<cost.count()<<"s\n"; });
    }
    for (int i = 0; i < thr_count; i++)
    {
        threads[i].join();
    }
    // 7.计算总耗时-为线程中最长的耗时
    double max_cost = cost_arry[0];
    for (int i = 0; i < thr_count; i++)
    {
        max_cost = max_cost < cost_arry[i] ? cost_arry[i] : max_cost;
    }
    size_t msg_per_sec = msg_count / max_cost;                       // 每秒输出多少条消息
    size_t size_per_sec = (msg_count * msg_len) / (max_cost * 1024); // 每秒输出多少KB消息
    // 8.打印数据
    std::cout << "\t总耗时：" << max_cost << "s,\n";
    std::cout << "\t每秒输出日志数量：" << msg_per_sec << "条,\n";
    std::cout << "\t每秒输出日志大小：" << size_per_sec << "KB,\n";
}

void sync_bench()
{
    std::unique_ptr<PRJLOG::LoggerBuilder> logger(new PRJLOG::GlobalLoggerBuilder());
    logger->BuildLoggername("SyncLogger");
    logger->BuildLoggerType(PRJLOG::LoggerType::Logger_Sync);
    logger->BuildFormatter("[%c][%f:%l]%m%n");
    logger->BuildSink<PRJLOG::FileSink>("./logfile/sync.log");
    logger->Builder();
    bench("SyncLogger", 1, 1000000, 100);
}
void async_bench()
{
    std::unique_ptr<PRJLOG::LoggerBuilder> logger(new PRJLOG::GlobalLoggerBuilder());
    logger->BuildLoggername("AsyncLogger");
    logger->BuildLoggerType(PRJLOG::LoggerType::Logger_Async);
    logger->BuildEnableUnsafe();
    logger->BuildFormatter("%m%n");
    logger->BuildSink<PRJLOG::FileSink>("./logfile/async.log");
    logger->Builder();
    bench("AsyncLogger", 3, 1000000, 100);
}

int main()
{
    async_bench();
    return 0;
}